package com.bootdo.app.util;

import java.io.IOException;
import java.util.Date;
import java.util.List;

import com.bootdo.payee.dao.PayeeDao;
import com.bootdo.payee.dao.PaymentCodeDao;
import com.bootdo.payee.domain.PayeeDO;
import com.bootdo.payee.domain.PaymentCodeDO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.bootdo.common.config.ApplicationContextRegister;
import com.bootdo.common.config.Constant;
import com.bootdo.common.redis.lock.CommonRedisLock;
import com.bootdo.common.utils.DateUtils;
import com.bootdo.mq.RabbitUtil;
import com.rabbitmq.client.Channel;

/**
 * @program: bootdo
 * @packageName: com.bootdo.app.util
 * @className: PayeeSortUtil
 * @description: 用户排队Util
 * @create: 2020-03-15 20:54
 */
@Component
public class PayeeSortUtil {

    private static final Logger logger = LoggerFactory.getLogger(PayeeSortUtil.class);

    @Autowired
    private RabbitUtil rabbitUtil;
    @Autowired
    protected StringRedisTemplate stringRedisTemplate;

    @Autowired
    private PayeeDao payeeMapper;

    @Autowired
    private PaymentCodeDao paymentCodeMapper;

    @RabbitListener(queues = "topic.change.sort",containerFactory = "customContainerFactory")
    public void changeSort(Channel channel, Message message){
        try {
            String msg = new String(message.getBody(),"utf-8");
            JSONObject jsonObject= JSONObject.parseObject(msg);
            Integer type = jsonObject.getInteger("payType");
            logger.info("接收到来自渠道信息发送改变信息，渠道信息："+type+"，>>>>>>>>>>>>>>>>>>>>>>>>>接收到数据"+msg);
            CommonRedisLock commonRedisLock = new CommonRedisLock(stringRedisTemplate);
            List<String> list = commonRedisLock.lRangeAll(Constant.PASSAGEWAY + type);
            logger.info("====推送排队=====" + JSONObject.toJSONString(list));
            if (list.size() > 0){
                for (int i = 0; i < list.size(); i++) {
                    logger.info("====推送排队=====" + list.get(i));
                    if (list.get(i) != null){
                        PayeeDO payee = payeeMapper.get(Long.valueOf(list.get(i)));
                        if (payee.getLineStatus()==1) {
                            JSONObject object = new JSONObject();
                            String queueName = Constant.QUEUE_START + list.get(i);
                            object.put("code",1);
                            object.put("date", DateUtils.format(new Date(),DateUtils.DATE_TIME_PATTERN));
                            object.put("userId", list.get(i));
                            object.put("payType",type);
                            logger.info("当前判断排队的类型为："+type);
                            switch (type){
                                case 1 :
                                    object.put("msg", "当前：" + (i + 1)+"；总："+ list.size() + "(支付宝固码)");
                                    break;
                                case 2 :
                                    object.put("msg", "当前：" + (i + 1)+"；总："+ list.size() + "(微信固码)");
                                    break;
                                case 3 :
                                    object.put("msg", "当前：" + (i + 1)+"；总："+ list.size() + "(H5跳转)");
                                    break;
                                case 4 :
                                    object.put("msg", "当前：" + (i + 1)+"；总："+ list.size() + "(支付宝账号或吱口令)");
                                    break;
                                default:
                                    object.put("msg", "您的排队已发生变化可以正常接单。");
                                    break;
                            }
                            object.put("payType",type);
                            logger.debug("前往通道："+queueName+"的消息已经成功发射，请等待接收"+ DateUtils.formatDate(new Date(),"yyyy-MM-dd HH:mm:ss.SSS"));
                            rabbitUtil.sendToQueue(queueName,object.toJSONString());
                        } else {
                            //获取当前用户使用的收款通道
                            PaymentCodeDO paymentCode = paymentCodeMapper.getCodeByOk(payee.getUserId());
                            commonRedisLock.lRemove(Constant.PASSAGEWAY + paymentCode.getPassagewayId(), 0, String.valueOf(payee.getUserId()));
                        }
                    }
                }
            }
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
            logger.info("消息topic.change.sort消费成功：id：{}",message.getMessageProperties().getDeliveryTag());
        } catch (IOException e) {
            e.printStackTrace();
            logger.error("业务处理异常："+e.getMessage());
            //丢弃这条消息
            try {
                //最后一个参数是：是否重回队列
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false,true);
            } catch (IOException e1) {
                logger.error("业务处理异常："+e1.getMessage());
                logger.error("消息消费失败：id：{}",message.getMessageProperties().getDeliveryTag());
            }
        }

    }

    @RabbitListener(queues = "topic.recive.heart",containerFactory = "customContainerFactory")
    public void reciveHeart(Channel channel,Message message){
        StringRedisTemplate redisTemplate = ApplicationContextRegister.getBean(StringRedisTemplate.class);
        CommonRedisLock commonRedisLock = new CommonRedisLock(redisTemplate,"topic.recive.heart");
        try {
            if (commonRedisLock.tryLock(3)) {
                String msg = new String(message.getBody(), "utf-8");
                JSONObject jsonObject = JSONObject.parseObject(msg);
                Long userId = jsonObject.getLong("userId");
                logger.debug("接收到用户，用户ID：【" + userId + "】心跳检测数据，>>>>>>>>>>>>>>>>>>>>>>>>>接收到数据" + msg);
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                logger.debug("消息topic.recive.heart消费成功：id：{}", message.getMessageProperties().getDeliveryTag());
                commonRedisLock.unlock();
            }
        } catch (IOException e) {
            e.printStackTrace();
            logger.error("业务处理异常："+e.getMessage());
            commonRedisLock.unlock();
            //丢弃这条消息
            try {
                //最后一个参数是：是否重回队列
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false,false);
            } catch (IOException e1) {

                logger.error("业务处理异常："+e1.getMessage());
                logger.error("消息消费失败：id：{}",message.getMessageProperties().getDeliveryTag());

                e1.printStackTrace();
            }
        }
    }

}
